package com.example.smartf.service.impl;

import com.example.smartf.model.mongo.Group;
import com.example.smartf.model.mysql.Deviceinfo;
import com.example.smartf.model.mysql.Traindata;
import com.example.smartf.mqtt.DownHandler;
import com.example.smartf.mqtt.UpMqtt;
import com.example.smartf.repository.mongoDB.MongoGroupUtil;
import com.example.smartf.repository.mysql.DeviceinfoRepository;
import com.example.smartf.repository.mysql.TraindataRepository;
import com.example.smartf.service.RootService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
public class RootServiceImpl implements RootService {
    //日志记录器
    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private DeviceinfoRepository deviceinfoRepository;

    @Autowired
    private MongoGroupUtil mongoGroupUtil;

    @Autowired
    private TraindataRepository traindataRepository;

    //root用户添加新设备（测试新设备）
    public String newdevtest(String deviceID){
        if(null != deviceinfoRepository.findByDeviceid(deviceID)){
            return "has";
        }

        DownHandler downHandler = new DownHandler();
        String res = downHandler.sendDownMesg(deviceID,"testconnecter","test connect");
        if( res.equals("time out") == false && res.equals("recvice error") == false && res != null ){
            logger.info("Root用户：测试新设备：" + deviceID +  " 连接有效！");
            return "valid";
        }else{
            logger.warn("Root用户：测试新设备：" + deviceID +  " 连接无效！");
            return "invalid";
        }
    }

    //root用户添加一个新设备（并不会在用户所属device中添加）
    public String addnewdev(String deviceID){
        if(null != deviceinfoRepository.findByDeviceid(deviceID)){
            return "has";
        }
//        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
//        String startday = df.format(new Date());
//        String startday = "-";
        Deviceinfo deviceinfo = new Deviceinfo(deviceID);
        deviceinfoRepository.save(deviceinfo);
        logger.info("Root用户：添加新设备：" + deviceID + " 成功！");

        return "success";
    }

    //root用户添加一个新的分组
    public String addnewgroup(String groupID){
        if(null != mongoGroupUtil.findByGroupID(groupID)){
            return "has";
        }
        Group newgroup = new Group(groupID);
        mongoGroupUtil.addGroup(newgroup);
        if(null == mongoGroupUtil.findByGroupID(groupID)){
            logger.warn("Root用户：添加新组：" + groupID + " 失败!");
            return "failed";
        }else{
            logger.info("Root用户：添加新组：" + groupID + " 成功!");
            return "success";

        }
    }


    //root用户删除一个分组
    public String delgroup(String groupID){
        if(null == mongoGroupUtil.findByGroupID(groupID)){
            return "not has";
        }
        Group group = mongoGroupUtil.findByGroupID(groupID);
        if( group.getUsers() == null || group.getUsers().length == 0 ){

        }else {
            return "userlist not null";
        }
        if( group.getDevices() == null || group.getDevices().length == 0){

        }else {
            return "devlist not null";
        }
        mongoGroupUtil.delGroup(groupID);
        if( null == mongoGroupUtil.findByGroupID(groupID)){
            logger.info("Root用户：删除分组：" + groupID + "成功");
            return "success";
        }else{
            logger.info("Root用户：删除分组：" + groupID + "失败");
            return "failed";
        }

    }

    //root用户显示所有分组
    public List<Group> showgroup(){
        return mongoGroupUtil.findAll();
    }

    //root用户给一个分组加用户
    public String adduser(String groupID,String username){
        if( null != mongoGroupUtil.findGroupByusername(username) ){
            return "has";
        }


        Group group = mongoGroupUtil.findByGroupID(groupID);
        List<String> users;
        if( null != group.getUsers() ) {
            users = new ArrayList<>(Arrays.asList(group.getUsers()));
        }else {
            users = new ArrayList<>();
        }
        users.add(username);
        String[] newusers = new String[users.size()];
        users.toArray(newusers);

        mongoGroupUtil.updateGroupUsers(groupID,newusers);

        if( true == mongoGroupUtil.userinGroup(groupID,username)){
            logger.info("Root用户：为组：" + groupID + " 添加了一个新用户：" + username + " 成功！");
            return "success";
        }else{
            logger.warn("Root用户：为组：" + groupID + " 添加了一个新用户：" + username + " 失败！");
            return "failed";
        }


    }

    //root用户给一个分组删除用户
    public String deluser(String groupID,String username){
        if( false == mongoGroupUtil.userinGroup(groupID,username) ){
            return "not has";
        }

        Group group = mongoGroupUtil.findByGroupID(groupID);
        List<String> users = new ArrayList<>(Arrays.asList(group.getUsers()));
        users.remove(username);
        String[] newusers = new String[users.size()];
        users.toArray(newusers);
        mongoGroupUtil.updateGroupUsers(groupID,newusers);

        if( false == mongoGroupUtil.userinGroup(groupID,username)){
            logger.info("Root用户：为组：" + groupID + " 删除了一个用户：" + username + " 成功！");
            return "success";
        }else{
            logger.warn("Root用户：为组：" + groupID + " 删除了一个用户：" + username + " 失败！");
            return "failed";
        }

    }

    //root用户给一个分组加设备
    public String adddevice(String groupID,String deviceID,String kind,String devicename,String remarks){

        Deviceinfo deviceinfo = deviceinfoRepository.findByDeviceid(deviceID);
        if( null == deviceinfo ){
            return "device not exsit";
        }
        if( deviceinfo.getStartday() != null ){
            return "device is already in use";
        }
        if( true == mongoGroupUtil.devinGroup(groupID,deviceID)){
            return "has";
        }

        //首先更改deviceinfo中设备起始时间 等启用信息
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String startday = df.format(new Date());
        int res = deviceinfoRepository.changedeviceExtrainfo(deviceID,kind,startday,devicename,remarks);
        if(res == 0){   //表示修改失败
            return "device not exsit";
        }

        //其次修改 MongoDB中 Group表中的组下设备
        Group group = mongoGroupUtil.findByGroupID(groupID);
        List<String> devs;
        if( null != group.getDevices() ) {
            devs = new ArrayList<>(Arrays.asList(group.getDevices()));
        }else {
            devs = new ArrayList<>();
        }
        devs.add(deviceID);
        String[] newdevs = new String[devs.size()];
        devs.toArray(newdevs);

        mongoGroupUtil.updateGroupDevices(groupID,newdevs);

        if( true == mongoGroupUtil.devinGroup(groupID,deviceID) ){
            logger.info("Root用户：为组：" + groupID + " 添加了一个新设备：" + deviceID + " 成功！");

            //开始订阅
            UpMqtt upMqtt = UpMqtt.getInstance();
            upMqtt.subscribe(deviceID);

            return "success";
        }else{
            logger.warn("Root用户：为组：" + groupID + " 添加了一个新设备：" + deviceID + " 失败！");
            deviceinfoRepository.changedeviceExtrainfo(deviceID,null,null,null,null);
            return "failed";
        }
    }

    //root用户给一个分组删除设备
    public String deldevcie(String groupID,String deviceID){
        if( false == mongoGroupUtil.devinGroup(groupID,deviceID)){
            return "not has";
        }

        Deviceinfo tempdev = deviceinfoRepository.findByDeviceid(deviceID);
        int res = deviceinfoRepository.changedeviceExtrainfo(deviceID,null,null,null,null);
        if(res == 0){
            return "device not exsit";
        }

        List<Traindata> traindatas = traindataRepository.findAllByTraindataKeyDeviceIDOrderByTraindataKey_Days(deviceID);

        Group group = mongoGroupUtil.findByGroupID(groupID);
        List<String> devs = new ArrayList<>(Arrays.asList(group.getDevices()));
        devs.remove(deviceID);
        String[] newdevs = new String[devs.size()];
        devs.toArray(newdevs);

        mongoGroupUtil.updateGroupDevices(groupID,newdevs);
        //删除该设备对应的 训练数据
        traindataRepository.deleteAllByTraindataKeyDeviceID(deviceID);

        if( false == mongoGroupUtil.devinGroup(groupID,deviceID) ){
            logger.info("Root用户：为组：" + groupID + " 删除了一个设备：" + deviceID + " 成功！");


            //取消订阅
            UpMqtt upMqtt = UpMqtt.getInstance();
            upMqtt.cancelsub(deviceID);

            return "success";
        }else{
            logger.warn("Root用户：为组：" + groupID + " 删除了一个设备：" + deviceID + " 失败！");
            deviceinfoRepository.changedeviceExtrainfo(deviceID,tempdev.getKind(),tempdev.getStartday(),tempdev.getDevicename(),tempdev.getRemarks());
            traindataRepository.saveAll(traindatas);
            return "failed";
        }
    }
}
